package com.gk.panda.apis.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gk.panda.apis.Vo.RoleVo;
import com.gk.panda.apis.dto.DispatchButtonDto;
import com.gk.panda.apis.dto.RoleDto;
import com.gk.panda.apis.dto.RoleSearchDto;
import com.gk.panda.apis.mapper.RoleMapper;
import com.gk.panda.apis.service.RoleService;
import com.gk.panda.apis.service.UserService;
import com.gk.panda.commons.util.UserUtil;
import com.gk.panda.pojo.MenuBtns;
import com.gk.panda.pojo.MenuButton;
import com.gk.panda.pojo.Role;
import com.gk.panda.pojo.User;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private UserService userService;

    /**
     * 根据id删除角色
     * @param id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteRole(int id) {
        RoleMapper roleMapper = this.getBaseMapper();
        List<User> users = userService.getUserByRoleId(id);
        if (users.size() > 0) return -1;
        roleMapper.deleteMenuByRoleId(id);
        return roleMapper.deleteById(id);
    }

    /**
     * 添加角色
     * @param roleDto
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveRole(RoleDto roleDto) {
        String username = UserUtil.getCurrentUser();
        boolean success = true;
        Role role = new Role();
        role.setCreateUser(username);
        role.setName(roleDto.getName());
        role.setRemark(roleDto.getRemark());
        role.setType(roleDto.getType());
        int i = this.baseMapper.insert(role);
        if (i != 1) {
            success = false;
        }
        Integer id = role.getId();
        List<HashMap<String, Object>> permission = roleDto.getPermission();
        DispatchButtonDto buttonDto = new DispatchButtonDto();
        buttonDto.setRoleId(id);
        List<MenuButton> menuButtons = new ArrayList<>();
        for (HashMap<String, Object> map : permission) {
            String menuName = (String) map.get("name");
            int menuId = this.baseMapper.getMenuIdByName(menuName);
            MenuButton menuButton = new MenuButton();
            menuButton.setMenuId(menuId);
            List<Integer> btns = (List<Integer>) map.get("btns");
            String btnStr = "";
            for (Integer btn : btns) {
                btnStr += btn+",";
            }
            btnStr = btnStr.substring(0,btnStr.length()-1);
            menuButton.setBtnIds(btnStr);
            menuButtons.add(menuButton);
        }
        buttonDto.setMenuButtons(menuButtons);
        this.baseMapper.dispatchMenuButton(buttonDto);
        return success;
    }

    /**
     * 分页查询角色列表
     * @param searchDto
     * @return
     */
    @Override
    public IPage<RoleVo> searchRoles(RoleSearchDto searchDto) {
        List<RoleVo> roleVos = new ArrayList<>();
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        String name =searchDto.getName();
        if(!StringUtils.isEmpty(name)){
            wrapper.and(queryWrapper -> {
                queryWrapper.like("name", name)
                        .or().like("remark",name)
                        .or().like("create_user",name);
            });
        }
        List<Role> roles = this.list(wrapper);
        for (Role role : roles) {
            List<MenuBtns> menuBtns = this.baseMapper.getPermissionById(role.getId());
            List<HashMap<String,Object>> permission = new ArrayList<>();
            for (MenuBtns menuBtn : menuBtns) {
                HashMap<String, Object> map = new HashMap<>();
                map.put("name",menuBtn.getName());
                map.put("btns", Arrays.stream(menuBtn.getBtns().split(",")).mapToInt(Integer::parseInt).toArray());
                permission.add(map);
            }
            RoleVo roleVo = new RoleVo();
            roleVo.setId(role.getId());
            roleVo.setName(role.getName());
            roleVo.setStatus(role.getStatus());
            roleVo.setCreateTime(role.getCreateTime());
            roleVo.setCreateUser(role.getCreateUser());
            roleVo.setRemark(role.getRemark());
            roleVo.setType(role.getType());
            roleVo.setPermission(permission);
            roleVos.add(roleVo);
        }
        List pageList = new ArrayList<>();
        int pageNum = searchDto.getPageNumber();
        int pageSize = searchDto.getPageSize();
        int curIdx = pageNum > 1 ? (pageNum - 1) * pageSize : 0;
        for (int i = 0; i < pageSize && curIdx + i < roleVos.size(); i++) {
            pageList.add(roleVos.get(curIdx + i));
        }
        IPage<RoleVo> page = new Page<>(pageNum, pageSize);
        page.setRecords(pageList);
        page.setTotal(roleVos.size());
        return page;
    }

    /**
     * 修改角色
     * @param roleDto
     * @return
     */
    @Override
    public boolean updateRole(RoleDto roleDto) {
        RoleMapper roleMapper = this.getBaseMapper();
        Role role = this.getById(roleDto.getId());
        role.setName(roleDto.getName());
        role.setType(roleDto.getType());
        role.setRemark(roleDto.getRemark());
        boolean update = this.updateById(role);
        if (!update) return false;
        roleMapper.deleteMenuByRoleId(roleDto.getId());
        List<HashMap<String, Object>> permission = roleDto.getPermission();
        DispatchButtonDto buttonDto = new DispatchButtonDto();
        buttonDto.setRoleId(roleDto.getId());
        List<MenuButton> menuButtons = new ArrayList<>();
        for (HashMap<String, Object> map : permission) {
            String menuName = (String) map.get("name");
            int menuId = this.baseMapper.getMenuIdByName(menuName);
            MenuButton menuButton = new MenuButton();
            menuButton.setMenuId(menuId);
            List<Integer> btns = (List<Integer>) map.get("btns");
            String btnStr = "";
            for (Integer btn : btns) {
                btnStr += btn+",";
            }
            btnStr = btnStr.substring(0,btnStr.length()-1);
            menuButton.setBtnIds(btnStr);
            menuButtons.add(menuButton);
        }
        buttonDto.setMenuButtons(menuButtons);
        this.baseMapper.dispatchMenuButton(buttonDto);
        return true;
    }
}
